﻿using System;
using System.Linq;
using Omu.ValueInjecter;
using TrafficWatcher.Infrastructure;
using TrafficWatcher.Models.DirectionsProvider;

namespace TrafficWatcher.Models
{
    public class Settings
    {
        private IDirectionsProvider currentDirectionsProvider;
        private string start;
        private string finish;
        private bool doesTheApplicationRunAtStartup;

        protected Settings()
        {}

        public static Settings Load(IEnvironmentContext enviroment, DirectionsProviderRepository directionsProviderRepository)
        {
            var settings = new Settings();

            var settingsDto = enviroment.LoadSettings();
            if (settingsDto != null)
            {
                settings.InjectFrom(settingsDto);
                settings.CurrentDirectionsProvider =
                    directionsProviderRepository.DirectionsProviders.FirstOrDefault(
                        provider => provider.Name == settingsDto.CurrentDirectionsProviderName);
            }

            settings.DoesTheApplicationRunAtStartup = enviroment.DoesTheApplicationRunAtStartup();

            if (settings.CurrentDirectionsProvider == null)
            {
                settings.CurrentDirectionsProvider = directionsProviderRepository.DirectionsProviders[0];
            }

            return settings;
        }

        public string Start
        {
            get { return start; }
            set { SetProperty(ref start, value); }
        }

        public string Finish
        {
            get { return finish; }
            set { SetProperty(ref finish, value); }
        }

        public IDirectionsProvider CurrentDirectionsProvider
        {
            get { return currentDirectionsProvider; }
            set { SetProperty(ref currentDirectionsProvider, value); }
        }

        public bool DoesTheApplicationRunAtStartup
        {
            get { return doesTheApplicationRunAtStartup; }
            set { SetProperty(ref doesTheApplicationRunAtStartup, value); }
        }

        public event EventHandler SettingsChanged;

        
        public void Save(IEnvironmentContext enviroment)
        {
            var settingsDto = new SettingsDto { CurrentDirectionsProviderName = currentDirectionsProvider.Name };
            settingsDto.InjectFrom(this);
            enviroment.SaveSettings(settingsDto);
            enviroment.ManageTheApplicationRunAtStartup(DoesTheApplicationRunAtStartup);
        }

        private void SetProperty<T>(ref T storage, T value)
        {
            if (!Equals(storage, value))
            {
                storage = value;
                var handler = SettingsChanged;
                if (handler != null) handler(this, EventArgs.Empty);
            }
        }
    }
}
